/* ----------------------------------------------------------------------------
* File: module_controller_impl.cpp
*
* Desc: Module controller implementation for Skype plugin
*
* Created: 13/07/2011, by Alexey Korshunov
* ---------------------------------------------------------------------------- */
#include "module_controller_impl.h"


namespace ModuleManagement
{
	std::auto_ptr<ModuleController> CreateModuleController()
	{
		std::auto_ptr<ModuleController> controller;
		try
		{
			std::auto_ptr<ModuleController> obj(new ModuleControllerImpl());
			controller = obj;
		}
		catch(...)
		{
		}
		return controller;
	}
}

namespace ModuleManagement
{
	Common::Error ModuleControllerImpl::RegisterModule(const BaseModule* module, size_t& ID)
	{
		ID = m_Modules.size() + m_ChatModules.size();
		std::tr1::shared_ptr<BaseModule> obj(const_cast<BaseModule*>(module));
		m_Modules[ID] = obj;
		(const_cast<BaseModule*>(module))->SetID(ID);
		return Common::SKYPE_SUCCESS;
	}

	Common::Error ModuleControllerImpl::RegisterModule(const BaseModule* module, const std::string& ChatName, size_t& ID)
	{
		ID = m_Modules.size() + m_ChatModules.size();
		std::tr1::shared_ptr<BaseModule> obj(const_cast<BaseModule*>(module));
		m_ChatModules[ID] = ModuleChatPair(obj, ChatName);
		(const_cast<BaseModule*>(module))->SetID(ID);
		return Common::SKYPE_SUCCESS;
	}

	Common::Error ModuleControllerImpl::UnregisterModule(size_t ID)
	{
		ModuleMap::iterator it1 = m_Modules.find(ID);
		if (it1 != m_Modules.end())
		{
			m_Modules.erase(it1);
			return Common::SKYPE_SUCCESS;
		}

		ModuleChatMap::iterator it2 = m_ChatModules.find(ID);
		if (it2 != m_ChatModules.end())
		{
			m_ChatModules.erase(it2);
			return Common::SKYPE_SUCCESS;
		}

		return Common::SKYPE_ERROR;
	}

	const BaseModule* ModuleControllerImpl::FindModuleByID(size_t ID)
	{
		ModuleMap::const_iterator it1 = m_Modules.find(ID);
		if (it1 != m_Modules.end())
			return it1->second.get();

		ModuleChatMap::const_iterator it2 = m_ChatModules.find(ID);
		if (it2 != m_ChatModules.end())
			return it2->second.first.get();

		return NULL;
	}

	std::vector<BaseModule*> ModuleControllerImpl::FindModulesByChat(const std::string& ChatName,
		const ModuleType& type /* = MODULE_TYPE_UNKNOWN*/)
	{
		if (type == MODULE_TYPE_UNKNOWN)
			return GetAllModulesByChat(ChatName);
		else
			return GetSpecificModuleByChat(ChatName, type);
	}

	std::vector<BaseModule*> ModuleControllerImpl::GetAllModulesByChat(const std::string& ChatName)
	{
		std::vector<BaseModule*> modules;
		for (ModuleChatMap::iterator i = m_ChatModules.begin(), e = m_ChatModules.end(); i != e; ++i)
		{
			if (i->second.second == ChatName)
				modules.push_back(i->second.first.get());
		}
		return modules;
	}

	std::vector<BaseModule*> ModuleControllerImpl::GetSpecificModuleByChat(const std::string& ChatName, const ModuleType& type)
	{
		std::vector<BaseModule*> modules;
		for (ModuleChatMap::iterator i = m_ChatModules.begin(), e = m_ChatModules.end(); i != e; ++i)
		{
			if ((i->second.second == ChatName) && (i->second.first->GetType() == type))
				modules.push_back(i->second.first.get());
		}
		return modules;
	}
}